generic
   type individu (<>) is private;
   type cercle (<>) is private;
   type texte (<>) is private;
   type mur (<>) is private;
   with function creer (m : individu) return mur is <>;
   with function afficher (mu : mur; m : individu; t : texte; i : natural) return mur is <>;
   with function est_defini (mu : mur; i : natural) return boolean is <>;
   with function auteur (mu : mur; i : natural) return individu is <>;
   with function "<=" (m, n : individu) return boolean is <>;
   with function "<=" (c, d : cercle) return boolean is <>;

package Optimal is
   type Model is private;
   function creer return Model;

-----------------------------------------------------------------------------------------------
------------------- LES INDIVIDUS DE LA COMMUNAUTE---------------------
-----------------------------------------------------------------------------------------------

   function inscrire (x : Model; n : individu) return Model;
   function est_inscrit (x : Model; n : individu) return boolean;
   function nombre_inscrits (x : Model) return natural;
   function ieme_inscrit (x : Model; i : natural) return individu;
   function bloquer (x : Model; m : individu; n : individu) return Model;
   function debloquer (x : Model; m : individu; n : individu) return Model;
   function est_bloque (x : Model; m : individu; n : individu) return boolean;

------------------------------------------------------------------------------
------------------- LES CERCLES D'UN INDIVIDU --------------------------------
------------------------------------------------------------------------------

   function est_cercle_de (x : Model; n : individu; c : cercle) return boolean;
   function ajouter_cercle (x : Model; n : individu; c : cercle) return Model;
   function retirer_cercle (x : Model; n : individu; c : cercle) return Model;
   function nombre_cercles_de (x : Model; n : individu) return natural;
   function ieme_cercle (x : Model; n : individu; i : natural) return cercle;

-----------------------------------------------------------------------------------------------
------------------- LES MEMBRES D'UN CERCLE -------------------------------
-----------------------------------------------------------------------------------------------

   function est_membre_de (x : Model; m : individu; c : cercle; n : individu) return boolean;
   function ajouter_membre (x : Model; n : individu; c : cercle; p : individu) return Model;
   function retirer_membre (x : Model; n : individu; c : cercle; p : individu) return Model;
   function nombre_membres_de (x : Model; n : individu; c : cercle) return natural;
   function ieme_membre (x : Model; n : individu; c : cercle; i : natural) return individu;

-----------------------------------------------------------------------------------------------
------------------- POSTS ET COMMENTAIRES ----------------------------------
---------------------------------------------------------------------------------------
   function poster(x : Model; n : individu; c : cercle; t : texte) return Model;
   function commenter(x : Model; n : individu; i : natural; t : texte) return Model;
   function nombre_posts(x : Model) return natural;
   function consulter(x : Model; n : individu) return mur;

private
   type cercle_class;
   type individu_class;

   type cercles is array (positive range <>) of access cercle_class;
   type individus is array (positive range <>) of access individu_class;

   type individu_class is record
      indiv : access individu;
      listeCercles : access cercles;
      listeBloques : access individus;
      mur_individu : access mur;
   end record;

   type cercle_class is record
      cerc : access cercle;
      proprietaire : access individu;
      listeMembres : access individus;
   end record;

   type Model is record
      tab_individus : access individus;
      nombre_posts : natural;
   end record;
end Optimal;
